package horncomb.bpm.task.instance;

import horncomb.bpm.BpmContextHolder;
import horncomb.bpm.process.core.ExecutionContext;
import horncomb.bpm.process.core.Token;
import horncomb.bpm.task.core.TaskComment;
import horncomb.bpm.task.core.TaskInstance;
import horncomb.bpm.task.core.TaskInstanceEntity;
import horncomb.bpm.task.entity.DefaultTaskInstanceEntity;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 * @author Daniel
 */
public class DefaultTaskInstance implements Serializable, TaskInstance {
	private static final long serialVersionUID = 6885477068288997929L;
	private TaskInstanceEntity entity = new DefaultTaskInstanceEntity();

	/**
	 *
	 */
	public DefaultTaskInstance() {
		super();
	}

	public String getType() {
		return this.entity.getType();
	}

	/**
	 * {@inheritDoc}
	 */
	public Token getToken() {
		if (StringUtils.hasText(this.entity.getTokenId())) {
			return BpmContextHolder.getContext().getProcessManagementService()
					.findToken(this.entity.getTokenId());
		} else {
			return null;
		}
	}

	public void setToken(Token token) {
		this.entity.setTokenId(token.getId());
	}

	/**
	 * 启动任务
	 * @param context
	 */
	public void start(ExecutionContext context) {
		this.setStartedDate(new Date());
		BpmContextHolder.getContext().getTaskManagementServcie().update(this);
	}

	/**
	 * {@inheritDoc}
	 */
	public String[] getActorTerm() {
		if (StringUtils.hasText(this.entity.getActor())) {
			return new String[] { this.entity.getActor() };
		} else {
			return this.entity.getCandidate();
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isSubmitable() {
		if (this.getEndDate() == null
				// && this.getStartedDate() != null
				&& !this.isHolding()
				&& this.getActor() != null
				&& this.getActor().equals(
						BpmContextHolder.getContext().getCurrentActor())) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isRedoable() {
		return false;
	}

	/**
	 * {@inheritDoc}
	 */
	public void finish(Object contextModel) {
		this.setEndDate(new Date());
		BpmContextHolder.getContext().getTaskManagementServcie().update(this);
	}

	/**
	 * {@inheritDoc}
	 */
	public void finish(String transitionId, Object contextModel) {
		Assert.hasText(transitionId);
		// 单任务
		BpmContextHolder.getContext().getProcessManagementService()
				.performTransition(this.entity.getTokenId(), transitionId,
						contextModel);
		// if (!this.checkBeforeSubmit(context)) {
		// throw new TaskSubmitException("Task cannot be submitted.", this);
		// }
		this.finish(contextModel);
	}

	/**
	 * {@inheritDoc}
	 */
	public void addComment(String comment) {
		BpmContextHolder.getContext().getTaskManagementServcie().addComment(
				this.getId(), comment);
	}

	/**
	 * {@inheritDoc}
	 */
	public List<? extends TaskComment> getComments() {
		return BpmContextHolder.getContext().getTaskManagementServcie()
				.findTaskComments(this.getId());
	}

	/**
	 * {@inheritDoc}
	 */
	public TaskInstanceEntity getEntity() {
		return this.entity;
	}

	/**
	 * @param entity
	 *            the entity to set
	 */
	public void setEntity(TaskInstanceEntity entity) {
		this.entity = entity;
	}

	/**
	 * {@inheritDoc}
	 */
	public String getId() {
		return this.entity.getId();
	}

	/**
	 * @param id
	 *            the id to set
	 */
	public void setId(String id) {
		this.entity.setId(id);
	}

	/**
	 * {@inheritDoc}
	 */
	public String getName() {
		return this.entity.getName();
	}

	/**
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.entity.setName(name);
	}

	/**
	 * {@inheritDoc}
	 */
	public String getActor() {
		return this.entity.getActor();
	}

	/**
	 * @param actor
	 *            the actor to set
	 */
	public void setActor(String actor) {
		this.entity.setActor(actor);
	}

	/**
	 * {@inheritDoc}
	 */
	public String[] getCandidate() {
		return this.entity.getCandidate();
	}

	/**
	 * @param candidate
	 *            the candidate to set
	 */
	public void setCandidate(String[] candidate) {
		this.entity.setCandidate(candidate);
	}

	/**
	 * @return the createdDate
	 */
	public Date getCreatedDate() {
		return this.entity.getCreatedDate();
	}

	/**
	 * @param createdDate
	 *            the createdDate to set
	 */
	public void setCreatedDate(Date createdDate) {
		this.entity.setCreatedDate(createdDate);
	}

	/**
	 * {@inheritDoc}
	 */
	public Date getStartedDate() {
		return this.entity.getStartedDate();
	}

	/**
	 * @param startedDate
	 *            the startedDate to set
	 */
	public void setStartedDate(Date startedDate) {
		this.entity.setStartedDate(startedDate);
	}

	/**
	 * {@inheritDoc}
	 */
	public Date getEndDate() {
		return this.entity.getEndDate();
	}

	/**
	 * @param endDate
	 *            the endDate to set
	 */
	public void setEndDate(Date endDate) {
		this.entity.setEndDate(endDate);
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isHolding() {
		return this.entity.isHolding();
	}

	/**
	 * @param holding
	 *            the holding to set
	 */
	public void setHolding(boolean holding) {
		this.entity.setHolding(holding);
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isHiding() {
		return this.entity.isHiding();
	}

	/**
	 * {@inheritDoc}
	 */
	public void setHiding(boolean hiding) {
		this.entity.setHiding(hiding);
	}
}
